﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Prism.ViewModel;
using System.Collections.ObjectModel;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Unity;
using BBInterfaceNET.Events;
using BaseTypesLib;
using BBInterfaceNET.CommonServices;
using System.Diagnostics;
using ExplorerInfrastructure;
using System.IO;

namespace BBInterfaceNET.Designer.ViewModels
{
    public class DesignerViewModel:NotificationObject
    {
        private ObservableCollection<DocumentViewModel> files;
        private DocumentViewModel selFile;
        private IUnityContainer container;
        private IDesignerPersistenceService persistenceService;

        private IEventAggregator eventAggregator;

        public DesignerViewModel(IEventAggregator eventAggregator, IUnityContainer container,
            IDesignerPersistenceService persistenceService)
        {
            this.eventAggregator = eventAggregator;
            this.container = container;
            files = new ObservableCollection<DocumentViewModel>();
            this.persistenceService = persistenceService;

            CloseProjectEvent clProjEvt = eventAggregator.GetEvent<CloseProjectEvent>();
            clProjEvt.Subscribe(OnProjectClosed, ThreadOption.UIThread);
            FileOpenedEvent openFilesEvt = eventAggregator.GetEvent<FileOpenedEvent>();
            openFilesEvt.Subscribe(OnFileOpened, ThreadOption.UIThread);
            FileDeletedEvent delFilesEvt = eventAggregator.GetEvent<FileDeletedEvent>();
            delFilesEvt.Subscribe(OnFileDeleted, ThreadOption.UIThread);
            FileRenamedEvent renFileEvt = eventAggregator.GetEvent<FileRenamedEvent>();
            renFileEvt.Subscribe(OnFileRenamed, ThreadOption.UIThread);
            FileCreatedEvent createdEvt = eventAggregator.GetEvent<FileCreatedEvent>();
            createdEvt.Subscribe(OnFileCreated, ThreadOption.UIThread);

            this.PropertyChanged += (s, a) =>
            {
                if (a.PropertyName == "SelectedFile")
                {
                    IView view = container.Resolve<IView>("LayoutView");
                    if (view != null)
                    {
                        view.DataContext = SelectedFile;
                    }
                }
            };
        }

        public ObservableCollection<DocumentViewModel> Files
        {
            get { return files; }
        }
        public DocumentViewModel SelectedFile
        {
            get { return selFile; }
            set
            {
                if (selFile != value)
                {
                    if (selFile != null) selFile.IsActive = false;
                    selFile = value;
                    if (selFile != null) selFile.IsActive = true;
                    RaisePropertyChanged(() => SelectedFile);
                }
            }
        }

        public void OnProjectClosed(string projPath)
        {
            //for the moment close all the opened files
            foreach (DocumentViewModel fvm in files)
            {
                fvm.CloseCommand.Execute();
            }
        }

        public void OnFileCreated(string filePath)
        {
            ProjectInfo pi = ProjectInfo.GetInstance();
            persistenceService.WriteInitialFileData(filePath);
            FileDesignerViewModel fvm = container.Resolve<FileDesignerViewModel>();
            fvm.DisplayWidth = (int)pi.ScreenSize.Width;
            fvm.DisplayHeight = (int)pi.ScreenSize.Height;
            fvm.FontSize = pi.FontSize;
            fvm.ProjectRoot = Path.GetDirectoryName(pi.Path);
            fvm.FilePath = filePath;
            fvm.FileClosed += OnFileClosed;
            Files.Add(fvm);
            SelectedFile = fvm;
        }
        public void OnFileOpened(string filePath)
        {
            ProjectInfo pi = ProjectInfo.GetInstance();
            string dir = Path.GetDirectoryName(pi.Path);

            DocumentViewModel fvm = null;

            if (filePath.ToLower().EndsWith(ProjectFileConstants.FILE_EXTENSION))
            {
                fvm = container.Resolve<FileDesignerViewModel>();
                ((FileDesignerViewModel)fvm).DisplayWidth = (int)pi.ScreenSize.Width;
                ((FileDesignerViewModel)fvm).DisplayHeight = (int)pi.ScreenSize.Height;
                ((FileDesignerViewModel)fvm).FontSize = pi.FontSize;
            }
            else
                fvm = container.Resolve<ImageDesignerViewModel>();

            fvm.FilePath = filePath;
            fvm.ProjectRoot = dir;
            fvm.FileClosed += OnFileClosed;

            var qry = Files.Where(p => p.FilePath.ToLower().Equals(filePath.ToLower())).ToList();
            if (!qry.Any())
            {
                Files.Add(fvm);
                SelectedFile = fvm;
            }
            else
            {//is already opened
                SelectedFile = qry.First();
            }
        }

        public void OnFileDeleted(string filePath)
        {
            var file = files.Where(p => p.FilePath.ToLower().Equals(filePath.ToLower())).SingleOrDefault();
            if (file != null)
            {
                //the file is already deleted. just remove it. dirty does not matter
                Files.Remove(file);
            }
        }
        public void OnFileRenamed(FileDataInfo fileData)
        {
            //just change the path
            var file = Files.Where(p => p.FilePath.ToLower().Equals(fileData.OldPath.ToLower())).SingleOrDefault();
            if (file != null)
            {
                file.FilePath = fileData.NewPath;
                file.SaveCommand.Execute();
            }
        }

        private void OnFileClosed(object sender, EventArgs args)
        {
            DocumentViewModel fvm = sender as DocumentViewModel;
            if (fvm == null) return;
            fvm.FileClosed -= OnFileClosed;
            Files.Remove(fvm);
            if (Files.Count == 0)
            {
                eventAggregator.GetEvent<DocumentChangedEvent>().Publish(null);
                eventAggregator.GetEvent<FieldSelectedEvent>().Publish(null);
            }
        }
    }
}
